import {
  randomString
} from '@/utils'

import Tips from './tips'
import CryptoJS from 'crypto-js'
import Security from './security'

/**
 * 从服务器获取AccessToken的方法
 */
export async function authorize () {
  console.group('Auth')
  console.log('执行自动授权...')

  const code = await getMpCode()
  const token = await mpLoginAuthorize(code)
  console.log('微信授权结果:', token)

  const accessToken = token.access_token
  wx.setStorageSync('accessToken', accessToken)
  wx.setStorageSync('expiredTime', token.expired_at)
  console.log('AccessToken:', accessToken)
  console.groupEnd('Auth')
  return accessToken
}

/**
 * 判断token过期时间，判断是否要重新请求
 */
function getMpCode () {
  console.group('Auth')
  return new Promise((resolve) => {
    wx.login({
      success: (res) => {
        console.log('调用wx.login成功后拿到的返回值:', res)
        const {code} = res
        if (code) {
          console.log('----拿到了微信授权Code:', code)
          resolve(code)
        } else {
          console.log('----没拿到。微信登录Code获取失败:' + res.errMsg)
        }
      }
    })
  })
}

/**
 * 小程序原生api 获取登录的code属性值
 * 接口登录方法 获取accessToken
 * @param {*} code
 */
function mpLoginAuthorize (code) {
  Tips.loading()
  return new Promise((resolve) => {
    console.log('根据Code：', code)
    const params = generateSignature(code)
    console.log('同时生成签名参数并返回', params)
    wx.request({
      url: `${process.env.HOST}/authorize`,
      method: 'POST',
      data: params,
      success: (res) => {
        console.log('发起系统授权接口得到返回值：', res)
        const {statusCode, data} = res
        Tips.loaded()
        if (statusCode === 200) {
          mpvue.setStorageSync('mine', data.user)
          mpvue.setStorageSync('sessionKey', data.sessionKey)
          resolve(data.token)
        } else {
          Tips.error(data.message)
        }
      },
      fail: function (e) {
        console.log(e)
      }
    })
  })
}

/**
 * 生成签名字符串
 * @param {*} code
 */
function generateSignature (code) {
  const nonce = randomString(32)
  const systemInfo = wx.getSystemInfoSync()
  const { miniProgram } = wx.getAccountInfoSync()

  const build = miniProgram.envVersion === 'release' ? process.env.BUILD : 0
  let params = {
    appid: process.env.APP_ID,
    //
    build: build,
    code: code,
    timestamp: parseInt(Date.now() / 1000),
    //
    platform: systemInfo.platform,
    system: systemInfo.system,
    model: systemInfo.model,
    brand: systemInfo.brand
  }
  let str = ''
  for (let key of Object.keys(params).sort()) {
    str += params[key]
  }
  let secret = process.env.APP_SECRET
  let sign = CryptoJS.SHA256(secret + str + nonce).toString(CryptoJS.enc.Hex)

  params['nonce'] = nonce
  params['sign'] = sign
  return params
}

/**
 * 对请求头的token进行AES加密
 * @param {*} data
 */
export function cryptoToken (data) {
  return Security.encrypt(data)
}

/**
 * 判断token过期时间，判断是否要重新请求
 */
export function needRequestToken () {
  const expiredTime = wx.getStorageSync('expiredTime')
  if (!expiredTime) {
    return
  }
  const now = new Date().getTime()
  if ((now + 86400 * 5) < expiredTime * 1000) {
    return
  }
  wx.removeStorageSync('accessToken')
  wx.removeStorageSync('expiredTime')
}
